package com.weike.bsp.model

import com.fasterxml.jackson.annotation.JsonIgnore
import io.r2dbc.spi.Row
import io.r2dbc.spi.RowMetadata
import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.io.Serializable
import java.time.Duration
import java.time.LocalDateTime
import java.util.function.BiFunction

/**
 * 用户token
 */
@Table("pub_access_token")
data class AccessToken(
    @Id
    var id: Long? = null,

    @Column("access_token")
    var token: String? = null,

    @Column("user_id")
    var userId: Long? = null,

    @Column("username")
    var username: String? = null,

    @Column("is_enabled")
    var enabled: Boolean? = null,

    /**
     * 创建时间
     */
    @Column("created_at")
    var createdAt: LocalDateTime? = null,

    /**
     * 最近请求时间
     */
    @Column("last_request_at")
    var lastRequestAt: LocalDateTime? = null,

    /**
     * 过期时间
     */
    @Column("expired_at")
    var expiredAt: LocalDateTime? = null
) : Serializable {

    /**
     * 是否过期
     */
    @get:JsonIgnore
    val isExpired: Boolean
        get() = expiredAt?.isBefore(LocalDateTime.now()) ?: true

    @get:JsonIgnore
    val timeout: Duration
        get() = Duration.between(createdAt, expiredAt)

    /**
     * 使token过期
     */
    fun expireNow() {}

    companion object {
        private const val serialVersionUID = 6007909870326877545L

        @JvmStatic
        fun convert(t: Row, u: RowMetadata): AccessToken {
            val at = AccessToken()
            at.id = t.get("id", Long::class.java)
            at.userId = t.get("user_id", Long::class.java)
            at.token = t.get("access_token", String::class.java)
            at.username = t.get("username", String::class.java)
            at.enabled = t.get("is_enabled", Boolean::class.java)
            at.createdAt = t.get("created_at", LocalDateTime::class.java)
            at.lastRequestAt = t.get("last_request_at", LocalDateTime::class.java)
            at.expiredAt = t.get("expired_at", LocalDateTime::class.java)
            return at
        }
    }

    class Mapper: BiFunction<Row, RowMetadata, AccessToken> {
        override fun apply(t: Row, u: RowMetadata): AccessToken {
            return convert(t, u)
        }
    }

}
